--[[WEIGHTSTOOL]]--
--	Original				- 		Chocolate Blue
--	Weight STool 1.21 		- 		Spoco 	
--	Last versions 			- 		Chocolate Blue
--	GUI						-		Panthera Tigris

TOOL.Category		= "WeightSTool"
TOOL.Name			= "#Tool.weight.menutitle"
TOOL.Command		= nil
TOOL.ConfigName		= ""

TOOL.ClientConVar["set"] = "1"

if CLIENT then
	language.Add( "Tool.weight.name", "WeightSTool" )
	language.Add( "Tool.weight.menutitle", "Weight" )
	language.Add( "Tool.weight.desc", "Set the weight of an object.." )
	language.Add( "Tool.weight.0", "Primary: Set   Secondary: Copy   Reload: Reset" )
	language.Add( "Tool.weight.set", "Weight of the object:" )
	language.Add( "Tool.weight.set_desc", "Set the weight" )
	language.Add( "Tool.weight.zeromass", "Weight must be above 0!" )
end

if SERVER and not Weights then Weights = {} end

local function SetMass( Player, Entity, Data )
	if not SERVER then return end

	if Data.Mass then
		local physobj = Entity:GetPhysicsObject()
		if physobj:IsValid() then physobj:SetMass(Data.Mass) end
	end

	duplicator.StoreEntityModifier( Entity, "mass", Data )
end
duplicator.RegisterEntityModifier( "mass", SetMass )

local function IsReallyValid(trace)
	if not trace.Entity:IsValid() then return false end
	if trace.Entity:IsPlayer() then return false end
	if SERVER and not trace.Entity:GetPhysicsObject():IsValid() then return false end
	return true
end

function TOOL:LeftClick( trace )
	if CLIENT and IsReallyValid(trace) then return true end
	if not IsReallyValid(trace) then return false end
	
	if not Weights[trace.Entity:GetModel()] then 
		Weights[trace.Entity:GetModel()] = trace.Entity:GetPhysicsObject():GetMass() 
	end
	local mass = tonumber(self:GetClientInfo("set"))
	
	if mass > 0 then
		SetMass( self:GetOwner(), trace.Entity, { Mass = mass } )
	else
		net.Start("WeightSTool_1")
		net.Send(self:GetOwner())
	end
	
	return true;
end

function TOOL:RightClick( trace )
	if CLIENT and IsReallyValid(trace) then return true end
	if not IsReallyValid(trace) then return end
	
	local mass = trace.Entity:GetPhysicsObject():GetMass()
	self:GetOwner():ConCommand("weight_set "..mass);
	return true;
end

function TOOL:Reload( trace )
	if CLIENT then return false end;
	if not IsReallyValid(trace) then return false end
	local pl = self:GetOwner()
	local weight = Weights[trace.Entity:GetModel()]
	if not weight then return end
	
	SetMass( self:GetOwner(), trace.Entity, { Mass = weight } )
	
	self.Weapon:EmitSound( Sound( "Airboat.FireGunRevDown" )	)
	self.Weapon:SendWeaponAnim( ACT_VM_PRIMARYATTACK )
	
	local effectdata = EffectData()
		effectdata:SetOrigin( trace.HitPos )
		effectdata:SetNormal( trace.HitNormal )
		effectdata:SetEntity( trace.Entity )
		effectdata:SetAttachment( trace.PhysicsBone )
	util.Effect( "selection_indicator", effectdata )	
	
	local effectdata = EffectData()
		effectdata:SetOrigin( trace.HitPos )
		effectdata:SetStart( pl:GetShootPos() )
		effectdata:SetAttachment( 1 )
		effectdata:SetEntity( self.Weapon )
	util.Effect( "ToolTracer", effectdata )
	
	return false
end

function TOOL:Think()
	if CLIENT then return end;
	local pl = self:GetOwner()
	local wep = pl:GetActiveWeapon()
	if not wep:IsValid() or wep:GetClass() != "gmod_tool" or pl:GetInfo("gmod_toolmode") != "weight" then return end
	local trace = pl:GetEyeTrace()
	if not IsReallyValid(trace) then return end
	pl:SetNetworkedFloat("WeightMass", trace.Entity:GetPhysicsObject():GetMass())
end

function TOOL.BuildCPanel( cp )

cp.CPObject = vgui.Create("Panel", cp)
cp.CPObject:Dock(TOP)
cp.CPObject:DockMargin(4, 20, 0, 0)
cp.CPObject:SetVisible(true)	

cp.CPObject.TextArea = cp.CPObject:Add("DTextEntry")
cp.CPObject.TextArea:SetDrawBackground(false)
cp.CPObject.TextArea:SetNumeric(true)
cp.CPObject.TextArea.OnChange = function(val)
	val = math.Clamp((tonumber(val:GetValue())) or 1, 1, 25000)
	if val then
		cp.CPObject.Scratch:SetValue(val)
		val = math.Clamp(tonumber(cp.CPObject.Scratch:GetFloatValue()) or 1, 1, 25000)
		cp.CPObject.Slider:SetSlideX(cp.CPObject.Scratch:GetFraction(val))
	end
end

cp.CPObject.Slider = cp.CPObject:Add("DSlider", cp.CPObject)
cp.CPObject.Slider:SetLockY(0.5)
cp.CPObject.Slider.TranslateValues = function(slider, x, y)
	local val = math.Clamp(x*25000, 1, 25000)
	if val then
		cp.CPObject.Scratch:SetValue(val)
		if cp.CPObject.TextArea != vgui.GetKeyboardFocus() then
			local str = cp.CPObject.Scratch:GetTextValue()
			if string.find(str,".",1,true) then str = string.Explode(".", str, true)[1] end
			cp.CPObject.TextArea:SetValue(str)
		end
	end
	return cp.CPObject.Scratch:GetFraction(), y
end
cp.CPObject.Slider:SetTrapInside(true)
Derma_Hook(cp.CPObject.Slider, "Paint", "Paint", "NumSlider")

cp.CPObject.Label = vgui.Create("DLabel", cp.CPObject)
cp.CPObject.Label:SetMouseInputEnabled(true)
cp.CPObject.Label:SetDark(true)
cp.CPObject.Label:SetText("Set weight")

cp.CPObject.Scratch = cp.CPObject.Label:Add("DNumberScratch")
cp.CPObject.Scratch:SetImageVisible(false)
cp.CPObject.Scratch:Dock(FILL)
cp.CPObject.Scratch.OnValueChanged = function()
	local val = math.Clamp(tonumber(cp.CPObject.Scratch:GetFloatValue()) or 1, 1, 25000)
	cp.CPObject.Slider:SetSlideX(cp.CPObject.Scratch:GetFraction(val))
	if cp.CPObject.TextArea != vgui.GetKeyboardFocus() then
		local str = cp.CPObject.Scratch:GetTextValue()
		if string.find(str,".",1,true) then str = string.Explode(".", str, true)[1] end
		cp.CPObject.TextArea:SetValue(str)
	end
end
cp.CPObject.Scratch:SetMin(1)
cp.CPObject.Scratch:SetMax(25000)
cp.CPObject.Scratch:SetDecimals(0)
cp.CPObject.Scratch:SetConVar("weight_set")

cp.CPObject.List = cp.CPObject:Add("CtrlListBox")
for i=100,25000,100 do cp.CPObject.List:AddOption(tostring(i), {weight_set = tostring(i)}) end

cp.CPObject:SetTall(32)

local X = 5
cp.CPObject.Label:SetPos(X, 0)
cp.CPObject.Label:SetWide(65, 0)
X = X+65
cp.CPObject.Slider:SetPos(X, 0)
cp.CPObject.Slider:SetWide(135)
X = X+155
cp.CPObject.TextArea:SetPos(X-10, 0)
cp.CPObject.TextArea:SetWide(35)
X = X+35
cp.CPObject.List:SetPos(X, 0)
cp.CPObject.List:SetWide(45)

local val = math.Clamp(GetConVarNumber("weight_set") or 1, 1, 25000)
if val then
	cp.CPObject.Scratch:SetValue(val)
	val = math.Clamp(tonumber(cp.CPObject.Scratch:GetFloatValue()) or 1, 1, 25000)
	cp.CPObject.Slider:SetSlideX(cp.CPObject.Scratch:GetFraction(val))
	if cp.CPObject.TextArea != vgui.GetKeyboardFocus() then
		local str = cp.CPObject.Scratch:GetTextValue()
		if string.find(str,".",1,true) then str = string.Explode(".", str, true)[1] end
		cp.CPObject.TextArea:SetValue(str)
	end
end

cp.CPObject.Slider:SetNotches(cp.CPObject:GetWide()/4)

end

if CLIENT then
	local TipColor = Color( 250, 250, 200, 255 )

	surface.CreateFont("GModWorldtip", {font = "coolvetica", size = 24, weight = 500})

	local function DrawWeightTip()
		local pl = LocalPlayer()
		local wep = pl:GetActiveWeapon()
		if not wep:IsValid() or wep:GetClass() != "gmod_tool" or pl:GetInfo("gmod_toolmode") != "weight" then return end
		local trace = pl:GetEyeTrace()
		if not IsReallyValid(trace) then return end
		
		local mass = LocalPlayer():GetNetworkedFloat("WeightMass") or 0
		local text = "Weight: "..mass
	
		local pos = (trace.Entity:LocalToWorld(trace.Entity:OBBCenter())):ToScreen()
		
		local black = Color( 0, 0, 0, 255 )
		local tipcol = Color( TipColor.r, TipColor.g, TipColor.b, 255 )
		
		local x = 0
		local y = 0
		local padding = 10
		local offset = 50
		
		surface.SetFont( "GModWorldtip" )
		local w, h = surface.GetTextSize( text )
		
		x = pos.x - w 
		y = pos.y - h 
		
		x = x - offset
		y = y - offset

		draw.RoundedBox( 8, x-padding-2, y-padding-2, w+padding*2+4, h+padding*2+4, black )
		
		
		local verts = {}
		verts[1] = { x=x+w/1.5-2, y=y+h+2 }
		verts[2] = { x=x+w+2, y=y+h/2-1 }
		verts[3] = { x=pos.x-offset/2+2, y=pos.y-offset/2+2 }
		
		draw.NoTexture()
		surface.SetDrawColor( 0, 0, 0, tipcol.a )
		surface.DrawPoly( verts )
		
		
		draw.RoundedBox( 8, x-padding, y-padding, w+padding*2, h+padding*2, tipcol )
		
		local verts = {}
		verts[1] = { x=x+w/1.5, y=y+h }
		verts[2] = { x=x+w, y=y+h/2 }
		verts[3] = { x=pos.x-offset/2, y=pos.y-offset/2 }
		
		draw.NoTexture()
		surface.SetDrawColor( tipcol.r, tipcol.g, tipcol.b, tipcol.a )
		surface.DrawPoly( verts )
		
		
		draw.DrawText( text, "GModWorldtip", x + w/2, y, black, TEXT_ALIGN_CENTER )
	end
	hook.Add("HUDPaint", "WeightWorldTip", DrawWeightTip)
	
	function ZMass()
		LocalPlayer():ConCommand("weight_set 1")
		GAMEMODE:AddNotify("#Tool.weight.zeromass", NOTIFY_ERROR, 6);
		surface.PlaySound( "buttons/button10.wav" )
	end
	net.Receive("WeightSTool_1", ZMass)
end